IoC is the broader principle — the framework controls the flow instead of your code. DI is one specific pattern that implements IoC where dependencies are injected into a class rather than the class fetching them. Every DI system is IoC, but not every IoC pattern is DI.
IoC is the overarching design principle: give up control of object creation and program flow to a framework or container. Dependency Injection is a concrete technique for achieving IoC — dependencies are passed in (injected) rather than pulled in by the dependent class.
IoC is a principle; DI is a pattern that implements that principle.
Other IoC patterns include the Service Locator pattern — but DI is more testable and explicit.
In NestJS, the IoC container uses constructor injection (a form of DI) to wire the application.
When you use @Injectable() and declare constructor parameters, you are applying DI inside an IoC container.